package foo.bar.wiki.radeox;

import foo.bar.radeox.engine.BaseRenderEngine;
import foo.bar.radeox.api.engine.WikiRenderEngine;
import foo.bar.radeox.api.engine.IncludeRenderEngine;
import foo.bar.radeox.api.engine.ImageRenderEngine;
import foo.bar.radeox.api.engine.context.InitialRenderContext;
import foo.bar.radeox.api.engine.context.RenderContext;
import foo.bar.wiki.services.WikiService;
import foo.bar.wiki.domain.Page;
import foo.bar.wiki.domain.Resource;
import foo.bar.wiki.web.action.page.PageActionBean;
import foo.bar.wiki.web.action.page.AddPageActionBean;
import foo.bar.wiki.web.action.general.ExternalLinkImageActionBean;
import foo.bar.wiki.web.action.general.MailToImageActionBean;
import foo.bar.wiki.web.action.general.ResourceRetrievalActionBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import net.sourceforge.stripes.util.UrlBuilder;

import java.util.Locale;

/**
 * @author tmjee
 * @version $Date$ $Id$
 */
public class DefaultWikiRenderEngine extends BaseRenderEngine implements WikiRenderEngine,
        IncludeRenderEngine, ImageRenderEngine {

    private static final Log LOG = LogFactory.getLog(DefaultWikiRenderEngine.class);

    public static final String RENDER_CONTEXT_SPACE_ID_PARAM_KEY = "RENDER_CONTEXT_SPACE_ID_PARAM_KEY";


    private WikiService wikiService;

    public DefaultWikiRenderEngine(WikiService wikiService, InitialRenderContext initialRenderContext) {
        super(initialRenderContext);
        this.wikiService = wikiService;
    }



    // === WikiRenderEngine interface ====================================================

    public boolean exists(String pageName, RenderContext renderContext) {
        String spaceId = getSpaceId(renderContext);
        Page page = wikiService.getSpacePageByName(spaceId, pageName);
        System.out.println("************************************* "+pageName+"="+(page));
        return (page != null);
    }

    public boolean showCreate(RenderContext renderContext) {
        // TODO: add security
        return true;
    }



    /**
     * eg. [name]
     *     name = name
     *     view = name
     *     anchor = none
     * eg. [alias|name]
     *     name = name
     *     view = alias
     *     anchor = none
     * eg. [alias|name#hash]
     *     name = name
     *     view = alias
     *     anchor = hash
     *
     * @param buffer
     * @param name
     * @param view
     * @param anchor
     */
    public void appendLink(StringBuffer buffer, String name, String view, String anchor, RenderContext renderContext) {
        String spaceId = getSpaceId(renderContext);
        Page page = wikiService.getSpacePageByName(spaceId, name);
        if (page != null) { // page exists
            UrlBuilder urlBuilder = new UrlBuilder(Locale.getDefault(), PageActionBean.class, true);
            urlBuilder.setEvent("view");
            urlBuilder.addParameter("page", page.getId());
            buffer.append("<a href='"+getContextPath()+urlBuilder.toString()+"'>"+name+"</a>");
        }
        else {
            appendCreateLink(buffer, name, view, renderContext);
        }
    }

    public void appendLink(StringBuffer stringBuffer, String name, String view, RenderContext renderContext) {
        appendLink(stringBuffer, name, view, null, renderContext);
    }

    public void appendCreateLink(StringBuffer buffer, String name, String view, RenderContext renderContext) {
        UrlBuilder urlBuilder = new UrlBuilder(Locale.getDefault(), AddPageActionBean.class, true);
        urlBuilder.setEvent("view");
        urlBuilder.addParameter("page.name", name);
        buffer.append(name+"<a href='"+getContextPath()+urlBuilder.toString()+"'>?</a>");
    }


    // === IncludeRenderEngine interface ==================================================

    public String include(String name, RenderContext renderContext) {
        String spaceId = getSpaceId(renderContext);
        Page page = wikiService.getSpacePageByName(spaceId, name);
        if (page != null) {
            return render(page.getContent());            
        }
        return "<span class='error'>Cannot find page in space ["+spaceId+"] with name ["+name+"]</span>";  // nothing to include
    }


    public String includeResource(String name, RenderContext renderContext) {
        String spaceId = getSpaceId(renderContext);
        Resource resource = wikiService.getResourceByNameAndSpaceId(name, spaceId);
        UrlBuilder urlBuilder = new UrlBuilder(Locale.getDefault(), ResourceRetrievalActionBean.class, true);
        urlBuilder.setEvent("view");
        urlBuilder.addParameter("space", spaceId);
        urlBuilder.addParameter("resourceName", name);

        if (resource.getMimeType().toLowerCase().startsWith("image")) {
            return "<img src='"+getContextPath()+urlBuilder.toString()+"'/>";
        }
        else {
            return "<a href='"+getContextPath()+urlBuilder.toString()+"'>"+name+"</a>";
        }
    }


    // === ImageRenderEngine interface ====================================================

    public String getExternalImageLink(RenderContext renderContext) {
        UrlBuilder urlBuilder = new UrlBuilder(Locale.getDefault(), ExternalLinkImageActionBean.class, true);
        urlBuilder.setEvent("view");
        return "<img src='"+getContextPath()+urlBuilder.toString()+"'/>";
    }

    public String getMailToImageLink(RenderContext renderContext) {
        UrlBuilder urlBuilder = new UrlBuilder(Locale.getDefault(), MailToImageActionBean.class, true);
        urlBuilder.setEvent("view") ;
        return "<img src='"+getContextPath()+urlBuilder.toString()+"'/>";
    }


    // ========= commons ===========
    protected String getSpaceId(RenderContext renderContext) {
        String spaceId = (String) renderContext.getParameters().get(RENDER_CONTEXT_SPACE_ID_PARAM_KEY);
        if ((spaceId == null) || (spaceId.trim().length() <= 0)) {
            throw new IllegalArgumentException("Cannot find space Id from RenderEngine ["+this+"]'s RenderContext ["+renderContext+"] with key ["+RENDER_CONTEXT_SPACE_ID_PARAM_KEY+"]");
        }
        return spaceId;
    }

    protected String getContextPath() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        String contextPath = servletRequestAttributes.getRequest().getContextPath();
        return contextPath;
    }
}
